﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using CommunitySystem.UploadService;

namespace CommunitySystem.PageView
{
    /// <summary>
    /// 文件上传类
    /// </summary>
    public class FileUploader
    {
        private UserFile _file;
        private long _dataLength;
        private long _dataSent;
      
        private UploadServiceClient _client;
        private string _initParams;
        private bool _firstChunk = true;
        private bool _lastChunk = false;
        private string _serverFilePath = string.Empty;

        /// <summary>
        /// 返回文件在服务器上的路径
        /// </summary>
        public string ServerFilePath
        {
            get { return _serverFilePath; }
            set { _serverFilePath = value; }
        }

        public FileUploader(UserFile file)
        {
            _file = file;

            _dataLength = _file.FileStream.Length;
            _dataSent = 0;
            _client =new UploadServiceClient();
            //事件绑定
            _client.GetServerFilePathCompleted += new EventHandler<GetServerFilePathCompletedEventArgs>(_client_GetServerFilePathCompleted);
            _client.GetServerFilePathAsync(_file.FileName, _firstChunk, _lastChunk);
            
            _client.StoreFileAdvancedCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(_client_StoreFileAdvancedCompleted);
            _client.CancelUploadCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(_client_CancelUploadCompleted);
            _client.AbortUploadCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(_client_AbortUploadCompleted);
            _client.ChannelFactory.Closed += new EventHandler(ChannelFactory_Closed);
        }

        /// <summary>
        /// 暂停上传
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _client_AbortUploadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //此处事件只是放在此处没有做处理，放在此处可以处理暂停操作的处理
        }

        #region
        /// <summary>
        /// 关闭ChannelFactory事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void ChannelFactory_Closed(object sender, EventArgs e)
        {
            ChannelIsClosed();
        }

        void _client_CancelUploadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //当取消上传完成后关闭Channel
            _client.ChannelFactory.Close();
        }

        /// <summary>
        /// Channel被关闭
        /// </summary>
        private void ChannelIsClosed()
        {
            if (!_file.IsDeleted)
            {
                if (UploadFinished != null)
                    UploadFinished(this, null);
            }
        }

        void _client_GetServerFilePathCompleted(object sender, GetServerFilePathCompletedEventArgs e)
        {
            if (e.Error == null)
            {
                _serverFilePath = e.Result;
                _file.ServerFileName = _serverFilePath;
            }
        }

        /// <summary>
        /// 取消上传
        /// </summary>
        public void CancelUpload()
        {
            _client.CancelUploadAsync(_file.FileName);
        }

        /// <summary>
        /// 暂停上传
        /// </summary>
        public void StopUpload()
        {
            _client.AbortUploadAsync(_file.FileName);
        }
        #endregion

        /// <summary>
        /// 上传完成事件处理对象声明
        /// </summary>
        public event EventHandler UploadFinished;

        public void UploadAdvanced(string initParams)
        {
            _initParams = initParams;

            UploadAdvanced();
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        private void UploadAdvanced()
        {

            byte[] buffer = new byte[4 * 4096];
            int bytesRead = _file.FileStream.Read(buffer, 0, buffer.Length);

            //文件是否上传完毕?
            if (bytesRead != 0)
            {
                _dataSent += bytesRead;

                if (_dataSent == _dataLength)
                    _lastChunk = true;//是否是最后一块数据，这样WCF会在服务端根据该信息来决定是否对临时文件重命名

                //上传当前数据块
                _client.StoreFileAdvancedAsync(_file.FileName, buffer, bytesRead, _initParams, _firstChunk, _lastChunk);

                //在第一条消息之后一直为false
                _firstChunk = false;

                //通知上传进度修改
                OnProgressChanged();
            }
            else
            {
                //当上传完毕后
                _file.FileStream.Dispose();
                _file.FileStream.Close();

                _client.ChannelFactory.Close();
            }
        }

        /// <summary>
        /// 修改进度属性
        /// </summary>
        private void OnProgressChanged()
        {
            _file.BytesUploaded = _dataSent;//注：此处会先调用FileCollection中的同名属性，然后才是_file.BytesUploaded属性绑定
        }

        void _client_StoreFileAdvancedCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)
        {
            //检查WEB服务是否存在错误
            if (e.Error != null)
            {
                //当错误时放弃上传
                _file.State = Constants.FileStates.Error;
            }
            else
            {
                //如果文件未取消上传并且没有的话，则继续上传
                if (!_file.IsDeleted && !_file.IsStop)
                    UploadAdvanced();
            }
        }

    }
}
